<!--滑动开关组件-->
<!--  
  传入参数：
    activeColor: 开启时的背景颜色 默认#34C759
    inactiveColor:关闭时的背景颜色 默认#DCDCDC
    bigBoxClass:外层盒子的class样式名
    btnClass:按钮class样式名
    defaultState:默认展示状态 默认false

  交互方法：
    change:调用父级函数，传递当前开关状态
-->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->

<template>
  <div
    class="components_btnSwitch"
    :class="bigBoxClass"
    :style="{ backgroundColor: switchState ? activeColor : inactiveColor }"
    ref="components_btnSwitch"
    @click.stop="btnSwitch"
  >
    <!-- 按键部分 -->
    <div
      :class="btnClass"
      :style="{
        transform: switchState ? `translateX(${btnMovingDistance}px)` : '',
      }"
      ref="components_btnSwitch_btn"
    ></div>
  </div>
</template>

<script>
// 组件引用
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// 接口+方法引用
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

export default {
  // 页面or组件 命名
  name: 'btnSwitch',

  props: {
    // 开启时的背景颜色 默认#34C759
    activeColor: {
      type: [String],
      default: '#34C759',
    },
    // 关闭时的背景颜色 默认#DCDCDC
    inactiveColor: {
      type: [String],
      default: '#DCDCDC',
    },
    // 外层盒子的class样式名
    bigBoxClass: {
      type: [String],
      default: '',
    },
    // 按钮class样式名
    btnClass: {
      type: [String],
      default: '',
    },
    // 默认展示状态 默认false
    defaultState: {
      type: [Boolean],
      default: false,
    },
  },

  // 参数变量声明区域
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  data() {
    return {
      switchState: this.defaultState, // 按键状态，默认为设置的样式
      btnMovingDistance: 0, // 按键移动状态
    }
  },
  // 监听使用区
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  watch: {
    // 监听按键状态值
    switchState: {
      handler(msg) {
        // 调用父级函数，传递当前开关状态
        this.$emit('change', msg)
      },
      immediate: true,
    },
    // 监听传入的class类名变化后，异步重新计算出移动的距离情况
    bigBoxClass() {
      setTimeout(() => {
        // 使用移动距离动态调整函数
        this.setBtnMovingDistance()
      }, 300)
    },
    btnClass() {
      setTimeout(() => {
        // 使用移动距离动态调整函数
        this.setBtnMovingDistance()
      }, 300)
    },

    // 监听传入的默认状态的变化
    defaultState(msg) {
      this.switchState = msg // 按键状态，默认为设置的样式
    },
  },

  // 无内存函数使用区域
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  methods: {
    // 移动距离动态调整函数
    setBtnMovingDistance() {
      let box = this.$refs.components_btnSwitch // 外层盒子的ref
      let btn = this.$refs.components_btnSwitch_btn // 按键的ref
      let boxWidth = box.clientWidth // 按键盒子的真实宽度
      let btnWidth = btn.clientWidth // 按键的真实宽度

      // 按键盒子左内边距
      let boxPaddingLeft = Number(
        window.getComputedStyle(box, null).paddingLeft.replace('px', '')
      )
      // 按键盒子右内边距
      let boxPaddingRight = Number(
        window.getComputedStyle(box, null).paddingRight.replace('px', '')
      )

      // 计算出按键点击后移动距离
      this.btnMovingDistance =
        boxWidth - btnWidth - boxPaddingLeft - boxPaddingRight
    },

    // 按键点击函数
    btnSwitch() {
      // 使用移动距离动态调整函数
      this.btnMovingDistance <= 0 && this.setBtnMovingDistance()
      this.switchState = !this.switchState
    },
  },

  // DOM挂载后
  // ---------------------------------------------------------------------------------------------
  mounted() {
    // 使用移动距离动态调整函数
    this.setBtnMovingDistance()
  },
}
</script>

<style scoped lang="less">
/* 滑动开关组件 */
.components_btnSwitch {
  height: 31px;
  width: 51px;
  border-radius: 25px;
  transition: all 0.3s;
  display: flex;
  align-items: center;
  padding: 0 2px;

  // 按键样式
  & > div {
    width: 27px;
    height: 27px;
    background-color: #fff;
    border-radius: 50%;
    border: 0.5px solid rgba(0, 0, 0, 0.04);
    transition: all 0.3s;
  }
}
</style>
